<?php
class Item{
	public $app;
	public $config;
	public $rootPath;
	public $params;


	public function __construct(){
		$this->app = Basic::app();
		$config = $this->config = $this->app->getConfigs();
		$this->rootPath = $config['base']['root'];
		$this->params = Basic::$route->params;
	}

	/**
	 *
	 * 创建url
	 * @param array $url such as array('post/new')
	 * @param array $params such as array('id'=>$id)
	 */
	public function createUrl($url,$params=array()){
		$s_url = BASE_URL."/index.php?r={$url}";
		foreach($params as $k=>$v){
			$s_url .='/'.urlencode($k).'/'.urlencode($v);
		}
		return $s_url;
	}

	public function render($name,$data=array(),$return=false){
		$config = $this->config;
		$viewName = 'view.'.$this->app->getRoute()->controller.'.'.$name;
		$_viewFile_ = $config['base']['root'].nameToPath($viewName);
		$_layoutFile_ = $config['base']['root'].nameToPath('view.layout.default');
		if($return==false){
			$content = $this->renderFile($_viewFile_,$data,true);
			$data['content'] = $content;
			$this->renderFile($_layoutFile_,$data);
		}else{
			$content = $this->renderFile($_viewFile_,$data,true);
		}
	}

	/**
	 * Renders a view file.
	 * @param string $_viewFile_ view file path
	 * @param array $_data_ optional data to be extracted as local view variables
	 * @param boolean $_return_ whether to return the rendering result instead of displaying it
	 * @return mixed the rendering result if required. Null otherwise.
	 */
	public function renderFile($_viewFile_,$_data_=null,$_return_=false)
	{
		if(is_array($_data_))
		extract($_data_,EXTR_PREFIX_SAME,'data');
		else
		$data=$_data_;
		if($_return_)
		{
			ob_start();
			ob_implicit_flush(false);
			require($_viewFile_);
			return ob_get_clean();
		}
		else
		require($_viewFile_);
	}

	/**
	 * 加载组件
	 * @param unknown_type $alias 组件别名
	 * @param unknown_type $params 组件参数
	 */
	public function component($alias, $params=array()){
		$coreAlias = 'system.class.component.'.$alias;
		if(file_exists(BASE_PATH.'/'.nameToPath($coreAlias)))
			$fullAlias = $coreAlias;
		else
			$fullAlias = 'component.'.$alias;
		$this->app->import($fullAlias);
		$realName = nameToPath($fullAlias);
		$pathinfo = pathinfo($realName);
		$className = ucwords($pathinfo['filename']);
		$refClass = new ReflectionClass($className);
		if($refClass->hasMethod('output')){
			$_obj = $refClass->newInstance($params);
			$refMethod = $refClass->getMethod('output');
			ob_start();
			ob_implicit_flush(false);
			$content = $refMethod->invoke($_obj);
			echo $content;
			return ob_get_clean();
		}else{
			throw new Dexception("Couldn't load Component, please check if the method named output exist");
		}
	}

	/**
	 * 加载结合体
	 */
	public function union($alias, $components = array(), $params = array()){
		extract($params);
		$data = 'hello';
		$coreAlias = 'system.class.union.'.$alias;
		if(file_exists(BASE_PATH.'/'.nameToPath($coreAlias)))
			$fullAlias = $coreAlias;
		else
			$fullAlias = 'union.'.$alias;
		$this->app->import($fullAlias);

		$realName = nameToPath($fullAlias);
		$pathinfo = pathinfo($realName);
		$className = ucwords($pathinfo['filename']);
		$refClass = new ReflectionClass($className);
		$_obj = $refClass -> newInstance($params);
		if($refClass->hasMethod('layout')){
			$refMethod = $refClass->getMethod('layout');
			ob_start();
			ob_implicit_flush(false);
			echo $refMethod->invoke($_obj);
			return ob_get_clean();
		}else{
			throw new Dexception("Can't found the method of 'layout',please check it in your union");
		}
	}

}